package com.aSemy.qotwReader.core;

import org.apache.commons.lang.StringEscapeUtils;

import com.aSemy.qotwReader.core.question.QuestionData;


/**
 * The commands given to Calibre's ebook converter.
 * @author Adam Semenenko
 */
public class CmdOptions
{
    /** The author used when assigning metadata. */
    private static final String author = "b3ta.com";
    /** The tag used when assigning metadata. */
    private static final String tag = "b3ta Question of the Week";
    
    /** Data gathered from the question. Contains title, date, comments, etc. */
    final private QuestionData data;
    
    /**
     * Used for creating the conversion options needed by Calibre for converting books.
     * Also creates commands for assigning metadata.
     * @param data Metadata gathered from the question, used for assigning book metadata.
     */
    public CmdOptions(QuestionData data)
    {
        this.data = data;
    }
    
    /**
     * Gets both the options for converting a book and for assinging metadata.
     * @return The options/metadata in a command line format.
     */
    public String getOptionsForConversion()
    {
        return getInputToEpubCmd() + " " + getMetadataOptions();
    }
    
    /**
     * Commands specific to converting a html file (a question).
     * 
     * TODO These commands seem to work well for epub. I think they might cause issue with other ebook types. 
     * 
     * @return A string containing the commands in the command line format used by the Calibre ebook converter.
     */
    private String getInputToEpubCmd()
    {
        String cmd = "";
        
        // What type of ebook reader the ebook should be tailored for.
        cmd += optionToCommandLine("--output-profile", data.getReaderType().toString());
        // No cover looks best.
        cmd += optionToCommandLine("--no-default-epub-cover");
        // It doesn't seem to like to convert using an svg cover, and the non-svg cover looks better anyway
        cmd += optionToCommandLine("--no-svg-cover"); 
        // I think this means it only looks at the images, but won't look at links except they're not saved.
        cmd += optionToCommandLine("--max-levels", "1");
        // Don't want any table of contents stuff.
        cmd += optionToCommandLine("--max-toc-links", "0");
        
        return cmd;
    }
    
    /**
     * Commands to assign the metadata. 
     * The metadata specific to the book is contained in {@link #data}. Other options (author, tag) are static variables
     * defined here in {@link #CmdOptions(QuestionData)}.
     * 
     * @return A string containing the commands for assigning metadata in the command line format used by the Calibre ebook converter.
     */
    private String getMetadataOptions()
    {
        String metadata = "";
        
        metadata += optionToCommandLine("--author-sort", CmdOptions.author);
        metadata += optionToCommandLine("--authors", CmdOptions.author);
        metadata += optionToCommandLine("--book-producer", CmdOptions.author);
        metadata += optionToCommandLine("--comments", data.getHtmlsafeComments());
        metadata += optionToCommandLine("--pubdate", data.getHtmlsafeDate());
        metadata += optionToCommandLine("--publisher", CmdOptions.author);
        metadata += optionToCommandLine("--timestamp", data.getHtmlsafeDate());
        metadata += optionToCommandLine("--title", data.getHtmlsafeTitle());
        metadata += optionToCommandLine("--title-sort", data.getHtmlsafeTitle());
        metadata += optionToCommandLine("--tags", CmdOptions.tag);
        
        return metadata;
    }
    
    /**
     * Used when an option has no arguments.
     * This function will ensure enough spacing and that the option is wrapped in quotes so that it is parsed correctly.
     * @param option The option to toggle
     * @return A string containing the command in a format that Calibre can use it.
     */
    private String optionToCommandLine(String option)
    {
        return " " + option + " ";
    }
    
    /**
     * Used to convert an option to a string that can be used as an arguement for Calibre's ebook converter.
     * Ensures the option and argument are properly spaced and the argument is wrapped in quotes and converted
     * to HTML (e.g. makes sure any quotes etc are escaped properly).
     * 
     * @param option The option to change
     * @param arg The argument of the option
     * @return A string containing the command and argument formatted so Calibre can use it. 
     */
    private String optionToCommandLine(String option, String arg)
    {
        return " " + option + " \"" + StringEscapeUtils.escapeHtml(arg) + "\" ";
    }
}
